/*
 * This code is a demo for Ian Upton's 2nd Life Application
 */
package application.controller;

import java.net.URLDecoder;
import application.externalServices.YahooTermExtractor;
import application.model.Blacklist;
import application.model.SndLifeWhitelist;
import application.service.SndLifeWhitelistService;
import application.model.EntityAccomplishment;
import application.model.EntityLookUp;
import application.model.EntitySearchResults;
import application.service.BlacklistService;
import application.service.EntityAccomplishmentService;
import application.service.EntitySearchResultsService;
import application.validator.SearchFormValidator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author aa6345
 */
@Controller
@SessionAttributes
public class SecondlifeappController {

    @Autowired
    private EntityAccomplishmentService entityAccomplishmentService;
    @Autowired
    private EntitySearchResultsService entitySearchResultsService;
    @Autowired
    private BlacklistService blacklistService;
    @Autowired
    private SndLifeWhitelistService sndLifeWhitelistService;
    //Remove when XML code is moved to a seperate class
    private String entityAdditionalDataXML = "";

    //public ModelAndView showSearch(@PathVariable String id, BindingResult result) {
    @RequestMapping(value = "/secondlifeapp", method = RequestMethod.GET, params = "name")
    public ModelAndView showSearch(@RequestParam("name") String entityName) {
        try {            
            /////System.out.println("**** You are searching for Entity!!!!");
            SearchFormValidator sfv = new SearchFormValidator(); //input validation tool
            HashMap<String, String> validatedFormValues = new HashMap<String, String>(); //contains validated input values

            //first find entity using input string
            validatedFormValues.put("searchTerm1", sfv.validateSearchTerm(URLDecoder.decode(entityName, "UTF-8")));
            List searchResults = entitySearchResultsService.listEntityLookUpByName(validatedFormValues);
            //ArrayList<EntitySearchResults> searchResultsMain = new ArrayList<EntitySearchResults>();
            //TODO: remove searchResultsTMP once scoring implemented (showSearchAndResultsEntity)
            //ArrayList<EntitySearchResults> searchResultsTMP = new ArrayList<EntitySearchResults>();
            //HashMap<String, List<EntitySearchResults>> searchResultsWithKW = new HashMap<String, List<EntitySearchResults>>();

            String pageToDisplay = "";

            if (searchResults == null || searchResults.isEmpty()) {

                return new ModelAndView("secondlifeapp").addObject("results", "No match found " + entityName);
            } else if (searchResults.size() > 1) {

                return new ModelAndView("secondlifeapp").addObject("results", "More than one match " + entityName);
            } else {
                //if one result only
                EntityLookUp esr = (EntityLookUp) searchResults.get(0);
                YahooTermExtractor urlcn = new YahooTermExtractor();
                //EntityAttributes entsAndAttribs = new EntityAttributes();
                List<Blacklist> blacklistTerms = blacklistService.listAllBlacklistTerms();
                ArrayList<String> matchedKeywordList = new ArrayList<String>();

                //get persons accomplishments
                List<EntityAccomplishment> listOfEntityAccomplishments = entityAccomplishmentService.listSelectedEntityAccomp(esr.getEntityID().toString());
                //genereate keywords

                /////System.out.println("START " + listOfEntityAccomplishments.size());
                //then search for matching entities
                //Yahoo term extractor
                int countBlockItems = 0;
                int mainCount = 1;
                String blockOfFive = "";

                for (int eaid = 0; eaid < listOfEntityAccomplishments.size(); eaid++) {
                    /////System.out.println(">88888< " + listOfEntityAccomplishments.get(eaid).getTitle());
                    HashMap<String, String> keywordVal = new HashMap<String, String>();
                    keywordVal.put("searchTerm1", listOfEntityAccomplishments.get(eaid).getTitle());

                    //if (!blackList.contains(s.toLowerCase().trim()) && !s.trim().equals("") && s.length()>0) {

                    if (listOfEntityAccomplishments.size() == mainCount) {
                        countBlockItems = 4;
                    }                    

                    if (listOfEntityAccomplishments.get(eaid).getTitle().split(" ").length > 2) {
                        if (countBlockItems < 5 && !listOfEntityAccomplishments.get(eaid).getTitle().equals("")) {
                            blockOfFive = blockOfFive + "****" + listOfEntityAccomplishments.get(eaid).getTitle().replace('"', ' ');
                            countBlockItems++;
                        }
                       

                    } else {
                        //check if in blacklist since keyword is short (3 words or less)
                        Boolean inBlacklist = false;  // used for blacklist check
                        //blacklist check
                        for (int blkX = 0; blkX < blacklistTerms.size(); blkX++) {
                            if (blacklistTerms.get(blkX).getBlacklistTerm().trim().equals(listOfEntityAccomplishments.get(eaid).getTitle())) {
                                inBlacklist = true;
                            }
                        }

                        if (inBlacklist == false) {
                            if (!matchedKeywordList.contains(listOfEntityAccomplishments.get(eaid).getTitle().trim())) {
                            List<EntitySearchResults> esr2 = entitySearchResultsService.listSelectedEntityByIDResults(listOfEntityAccomplishments.get(eaid).getTitle().trim(), esr.getEntityID().toString());

                            if (esr2.size() > 0 && listOfEntityAccomplishments.get(eaid).getTitle().trim().length() < 25) {
                                
                                    matchedKeywordList.add(listOfEntityAccomplishments.get(eaid).getTitle().trim());
                                }
                            }

                        } else {
                            /////System.out.println("BlackListed:" + listOfEntityAccomplishments.get(eaid).getTitle());
                        }
                    }


                    if (!blockOfFive.equals("") && (countBlockItems == 5 || ((eaid + 1) == listOfEntityAccomplishments.size()))) {

                        //if (s.split(" ").length > 2) {
                        /////System.out.println("Raw: " + blockOfFive);
                        urlcn.setFullText(blockOfFive);
                        urlcn.createURLWithText();
                        urlcn.startTermExtract();
                        urlcn.extractXMLKeywords();
                        // /////System.out.println("List of keywords "+mainCount+": "+urlcn.getExtractedKeywords().toString());
                        countBlockItems = 0;
                        blockOfFive = "";
                        //}

                    }

                    mainCount++;

                    //End Yahoo Term extractor

                }

                for (int kwdnum = 0; kwdnum < urlcn.getExtractedKeywords().size(); kwdnum++) {

                    Boolean inBlacklist = false;  // used for blacklist check
                    //blacklist check
                    for (int blkX = 0; blkX < blacklistTerms.size(); blkX++) {
                        if (blacklistTerms.get(blkX).getBlacklistTerm().trim().equals(urlcn.getExtractedKeywords().get(kwdnum).toString())) {
                            inBlacklist = true;
                        }
                    }

                    if (inBlacklist == false) {
                        if (!matchedKeywordList.contains(urlcn.getExtractedKeywords().get(kwdnum).toString().trim())) {
                        List<EntitySearchResults> esr3 = entitySearchResultsService.listSelectedEntityByIDResults(urlcn.getExtractedKeywords().get(kwdnum).toString(), esr.getEntityID().toString());

                        if (esr3.size() > 0) {
                            
                                matchedKeywordList.add(urlcn.getExtractedKeywords().get(kwdnum).toString().trim());
                            }
                        }

                    } else {
                        /////System.out.println("BlackListed:" + urlcn.getExtractedKeywords().get(kwdnum).toString());
                    }

                }

                //create output string with | as delimiter
                String outputStringFront = "";
                String outputStringBack = "";
                String outputString = "";
                List<SndLifeWhitelist> sndLifeWhitelistTerms = sndLifeWhitelistService.listAllSndLifeWhitelistTerms();

                for (int k1 = 0; k1 < matchedKeywordList.size(); k1++) {
                    //check if this keyword is in a white list. if so add it for output.
                    Boolean matchfound = false;
                    for (int sndL = 0; sndL < sndLifeWhitelistTerms.size(); sndL++) {
                        //System.out.println(sndLifeWhitelistTerms.get(sndL).getWhitelistitem()+" = "+matchedKeywordList.get(k1).trim());
                        if (sndLifeWhitelistTerms.get(sndL).getWhitelistitem().equals(matchedKeywordList.get(k1).trim())) {
                            matchfound=true;
                            break;
                        }
                    }
                    if (matchfound == true) {
                            outputStringFront += matchedKeywordList.get(k1).trim() + "|";
                        } else {
                            outputStringBack += matchedKeywordList.get(k1).trim() + "|";

                        }
                }

                System.out.println("Front: "+outputStringFront);
                System.out.println("Back: "+outputStringBack);

                //join front(whitelist approved) and back
                outputString = outputStringFront + outputStringBack;
                //remove last |
                String outputString2 = outputString.substring(0, outputString.length()-1);

                return new ModelAndView("secondlifeapp").addObject("results", outputString2);

            }

        } catch (Exception e) {
            return new ModelAndView("secondlifeapp").addObject("results", "Name search failed: \"" + entityName +"\"");
        }
    }

    @RequestMapping(value = "/secondlifeapp", method = RequestMethod.GET, params = "kwrd")
    public ModelAndView showKwrdSearch(@RequestParam("kwrd") String kword) {
        //try {
            List searchResults = null;  //list of query results
            SearchFormValidator sfv = new SearchFormValidator(); //input validation tool
            HashMap<String, String> validatedFormValues = new HashMap<String, String>(); //contains validated input values
            
            //validatedFormValues.put("searchTerm1", sfv.validateSearchTerm(URLDecoder.decode(kword, "UTF-8")));
            validatedFormValues.put("searchTerm1", sfv.validateSearchTerm(kword));
            validatedFormValues.put("searchOperator","none");
            validatedFormValues.put("searchTerm1Synonyms","");

            //get all matching entityAccomplishments (1 or more entities)
            searchResults = entitySearchResultsService.listSelectedEntitySearchResults(validatedFormValues);

            if(searchResults.isEmpty()) {
                return new ModelAndView("secondlifeapp").addObject("results", "Keyword search returned 0 matches! \"" + kword +"\"");
            }

            //get unique entity names and add them to outputString with | as delimiter
            String outputString = "";
            for(int i=0; i<searchResults.size(); i++) {
                if(!outputString.contains(searchResults.get(i).toString())) {
                    EntitySearchResults esr = (EntitySearchResults) searchResults.get(i);
                    outputString += esr.getEntityFname() + " " + esr.getEntitySname()+ "|";
                }
            }

            //remove last |
            String outputString2 = outputString.substring(0, outputString.length()-1);

            return new ModelAndView("secondlifeapp").addObject("results", outputString2);
        //} catch (Exception e) {
        //    return new ModelAndView("secondlifeapp").addObject("results", "Keyword search failed: \"" + kword +"\"");
        //}
    }
}
